/*
 * Copyright (c) kecp
 * Build on May 13, 2010
 */

package LBS;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

/**
 * translate the cell_id to location using www.location-api.com Location Service.
 * Note that the mobile is  requested to have a network connection.
 * @author kecp
 */
public class LocApiComLBS implements LocationService{

     Location locKeep = null;
     Cell cellKeep = null;
     final String apiKey =  "ta7djqg910asyv7zrype";

     static public byte[] getHttp(String url) throws IOException {

      HttpConnection c = null;
      InputStream is = null;
      byte[] data = null;

      try {
       c = (HttpConnection)Connector.open(url);
       c.setRequestProperty("Accept-Language", "zh-cn,en");  //指定语言
       int rc = c.getResponseCode();

       // handle the HTTP response codes used by the API
//       if(rc!=HttpConnection.HTTP_OK) {
//            switch(rc) {
//            case HttpConnection.HTTP_NO_CONTENT:
//             throw new IOException("The cell could not be "+
//                    "found in the database");
//            case HttpConnection.HTTP_BAD_REQUEST:
//             throw new IOException("Check if some parameter "+
//                    "is missing or misspelled");
//            case HttpConnection.HTTP_UNAUTHORIZED:
//             throw new IOException("Make sure the API key is "+
//                    "present and valid");
//            case HttpConnection.HTTP_FORBIDDEN:
//             throw new IOException("You have reached the limit "+
//                    "for the number of requests per day. The maximum "+
//                    "number of requests per day is currently 500.");
//            case HttpConnection.HTTP_NOT_FOUND:
//             throw new IOException("The cell could not be found "+
//                             "in the database");
//            default:
//             throw new IOException("HTTP response code: " + rc);
//            }
//       }

       is = c.openInputStream();

       int actual = 0;
       int len = (int)c.getLength();
       if(len>0) {
            int bytesread = 0 ;
            // the server returned a length so we can allocate
            // a byte array directly
            data = new byte[len];
            // loop until there is nothing more to read or
            // until buffer is full
            while((bytesread != len) && (actual != -1)) {
             actual = is.read(data, bytesread, len - bytesread);
             bytesread += actual;
            }
       } else {
            // the server is not returning a length
            // so we need a ByteArrayOutputStream
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            // create a 256 bytes read buffer to
            // improve reading performance
            byte buf[] = new byte[256];
            // loop for as long as we get data from the server
            // and add it to the output stream
            while((actual = is.read(buf, 0, 256))!=-1) {
             bos.write(buf, 0, actual);
            }
            bos.flush();
            data = bos.toByteArray();
       }
      } catch (ClassCastException e) {
       throw new IllegalArgumentException("Not an HTTP URL");
      } finally {
       try { if (c != null) c.close(); } catch(IOException e) {};
       try { if (is != null) is.close(); } catch(IOException e) {};
      }
      return data;
     }


     String parseKey( String src, String key ){
        int index ;
        int n;
        String str = null;
        key += "=\"";
        int keyLen = key.length();
        index = src.indexOf( key );
        if( index  != -1 ){
            index += keyLen ;
            n  = src.indexOf("\"" , index );
            if( n!= -1 ){
                    str = src.substring(index , n );
                    str = str.trim();
            }

        }
  //      System.out.println(key+":"+str);
        return str;

    }

     public Location parseXML(String xmlString) {
         Location loc = new Location();



            loc.setLon( parseKey( xmlString, "lon") );
            loc.setLat(  parseKey( xmlString, "lat") );
            loc.setAccuracy( parseKey( xmlString, "accuracy") );

       //     loc.setName(pos.optString("name"));


         return loc;
     }

    public Location getLocation(String cellid, String mnc, String mcc, String lac, int timeOut) {
         StringBuffer sb = new StringBuffer("http://www.location-api.com/cell/get/?");
         sb.append("key=" + apiKey );
         sb.append("&mcc="+mcc).append("&mnc="+mnc).append("&cellid="+cellid).append("&lac="+lac);



        String request = sb.toString(),response;
        System.out.println(request);
        Location loc = null;
        try {
            byte[] data = getHttp(request);
            String str = new String(data);
            System.out.println(str);
            loc = parseXML( str );
          //  locKeep = loc;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return loc;
    }

    public Location getPrevLocation() {
        return locKeep;
    }
    
     static public Location testLocApiComLBS() {
        Location loc;
        LocApiComLBS laLbs = new LocApiComLBS();
        Cell cell = new Cell();


         cell.cell_id =  "4008701";
         cell.mcc = "234";
         cell.mnc = "10";
         cell.lac = "0";

        loc = laLbs.getLocation(cell.cell_id, cell.mnc, cell.mcc, cell.lac, 1000);
        System.out.println( loc.toString());
      //  String.format();
        return loc;
    }

    public Location getCurLocation() {
          //取得当前基站信息
        Cell cell = new Cell();
        cell.updateNetworkInfo();

        if( cell.isAvailable() == false )
            return null;

        //检查是否跟前一个查询的基站一致
        if( locKeep != null && cellKeep != null && cellKeep.isEquals(cell) ) {
            return locKeep;
        }

        //查询并保存新的基站信息
        Location newLoct = getLocation( cell );
        locKeep = newLoct;
        cellKeep = cell;

        return newLoct;
    }

    public Location getLocation(Cell cell) {
        return getLocation(cell.cell_id,cell.mnc,cell.mcc,cell.lac, 1000);
    }

}
